#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File        :Project_CAN.py
@Desc        :
@Time        :2022/06/17 16:42:11
@Author        :WangWei
'''
from ast import If, Return
import binascii
import datetime
from email.headerregistry import Address
from email.message import Message
from gettext import npgettext
from pickle import TRUE
import string
import struct
import time
from pytest_assume.plugin import assume
import sys
import os
import logging
import allure
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.abspath(os.path.dirname(curPath) + os.path.sep + ".")
sys.path.append(rootPath)
sys.path.append(os.path.join(curPath,'commDriver'))
sys.path.append(os.path.join(curPath,'data'))
logging.info(sys.path)

from functools import reduce
from commDriver.TS_CAN import TSCAN, TSCAN_UDS,HIL_Obj
from commDriver.TS_CAN import TSMasterAPI
import Set_up
from commDriver.modbus_plc import *
from commDriver.power import power

def On_CANFD_EVENT(OBJ, ACAN):
    if (ACAN.contents.FIdentifier == 0x666 and ACAN.contents.FIdxChn == 0):
        # print("CANFD 0x666 回调接收成功")
        # for i in ACAN.contents.FData:
        #     print('%#x' % i, end=' ')
        # print('')
        pass
    if (ACAN.contents.FIdentifier == 0x777 and ACAN.contents.FIdxChn == 0):
        # print("CAN 0x777 回调接收成功")
        # for i in ACAN.contents.FData:
        #     print('%#x' % i, end=' ')
        # logging.info('')
        pass
OnCANFDevent = TSMasterAPI.OnTx_RxFUNC_CANFD(On_CANFD_EVENT)

Enable_0x127_RollingCounter_Error = True
Enable_0x127_Checksum_Error = True
Enable_0x2E9_RollingCounter_Error = True
Enable_0x2E9_Checksum_Error = True
Enable_0x300_RollingCounter_Error = True
Enable_0x300_Checksum_Error = True

Enable_0x121_Checksum_Error = False
Enable_0x121_RollingCounter_Error = False

Enable_0x240_Checksum_Error = False
Enable_0x240_RollingCounter_Error = False

Enable_0x242_Checksum_Error = False
Enable_0x242_RollingCounter_Error = False

Enable_0x341_Checksum_Error= False
Enable_0x341_RollingCounter_Error= False

Enable_0x342_Checksum_Error= False
Enable_0x342_RollingCounter_Error= False

Enable_0x123_Checksum_Error= False
Enable_0x123_RollingCounter_Error= False

Enable_0x1F0_Checksum_Error= False
Enable_0x1F0_RollingCounter_Error= False

Enable_0x220_Checksum_Error= False
Enable_0x220_RollingCounter_Error= False

Enable_0x222_Checksum_Error= False
Enable_0x222_RollingCounter_Error= False

Enable_0x223_Checksum_Error= False
Enable_0x223_RollingCounter_Error= False

Enable_0x321_Checksum_Error= False
Enable_0x321_RollingCounter_Error= False

Enable_0x422_Checksum_Error= False
Enable_0x422_RollingCounter_Error= False

Enable_0x1FC_Checksum_Error= False
Enable_0x1FC_RollingCounter_Error= False

Enable_0x24C_Checksum_Error= False
Enable_0x24C_RollingCounter_Error= False

Enable_0x11F_Checksum_Error= False
Enable_SAS_Scroll_Cycle_11F_Cnt_S_Error= False

Enable_0x12D_Checksum_Error= False
Enable_0x12D_RollingCounter_Error= False

Enable_0x3D9_Checksum_Error= False
Enable_0x3D9_RollingCounter_Error= False

Enable_0x1A7_Checksum_Error= False
Enable_0x1A7_RollingCounter_Error= False

Enable_0x195_Checksum_Error= False
Enable_0x195_RollingCounter_Error= False

Enable_0x134_Checksum_Error= False
Enable_0x134_RollingCounter_Error= False

Enable_0x109_Checksum_Error= False
Enable_0x109_RollingCounter_Error= False

Enable_0x258_Checksum_Error= False
Enable_0x258_RollingCounter_Error= False

Enable_0x2F6_CRC_Error= False
Enable_0x2F6_RollingCounter_Error= False


# Enable_0x2B6_RollingCounter= False

# project_rbs = TSCAN(Set_up.drive_type,Set_up.configure_baudrate)

# 回调函数，监控收到某帧报文后作何种操作
def On_CANFD_EVENT_Pre(OBJ, ACAN):

    # global Enable_0x2B6_RollingCounter

    global Enable_0x121_Checksum_Error
    global Enable_0x121_RollingCounter_Error

    global Enable_0x240_Checksum_Error
    global Enable_0x240_RollingCounter_Error

    global Enable_0x242_Checksum_Error
    global Enable_0x242_RollingCounter_Error

    global Enable_0x341_Checksum_Error
    global Enable_0x341_RollingCounter_Error

    global Enable_0x342_Checksum_Error
    global Enable_0x342_RollingCounter_Error

    global Enable_0x123_Checksum_Error
    global Enable_0x123_RollingCounter_Error

    global Enable_0x1F0_Checksum_Error
    global Enable_0x1F0_RollingCounter_Error

    global Enable_0x220_Checksum_Error
    global Enable_0x220_RollingCounter_Error

    global Enable_0x222_Checksum_Error
    global Enable_0x222_RollingCounter_Error

    global Enable_0x223_Checksum_Error
    global Enable_0x223_RollingCounter_Error

    global Enable_0x321_Checksum_Error
    global Enable_0x321_RollingCounter_Error

    global Enable_0x422_Checksum_Error
    global Enable_0x422_RollingCounter_Error

    global Enable_0x1FC_Checksum_Error
    global Enable_0x1FC_RollingCounter_Error

    global Enable_0x24C_Checksum_Error
    global Enable_0x24C_RollingCounter_Error

    global Enable_0x11F_Checksum_Error
    global Enable_SAS_Scroll_Cycle_11F_Cnt_S_Error

    global Enable_0x12D_Checksum_Error
    global Enable_0x12D_RollingCounter_Error

    global Enable_0x3D9_Checksum_Error
    global Enable_0x3D9_RollingCounter_Error

    global Enable_0x134_Checksum_Error
    global Enable_0x134_RollingCounter_Error

    global Enable_0x195_Checksum_Error
    global Enable_0x195_RollingCounter_Error

    global Enable_0x1A7_Checksum_Error
    global Enable_0x1A7_RollingCounter_Error

    global Enable_0x109_Checksum_Error
    global Enable_0x109_RollingCounter_Error

    global Enable_0x258_Checksum_Error
    global Enable_0x258_RollingCounter_Error

    global Enable_0x2F6_CRC_Error
    global Enable_0x2F6_RollingCounter_Error


    if ((ACAN.contents.FIdentifier == 0x12D) and (ACAN.contents.FIdxChn == 0)):
        if Enable_0x12D_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] >> 4  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = ((a << 4) & 0xF0) | (ACAN.contents.FData[6] & 0xF)
        else:
            ACAN.contents.FData[6] = 0 | (ACAN.contents.FData[6] & 0xF)
        # Checksum
        if Enable_0x12D_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0

    if (ACAN.contents.FIdentifier == 0x3D9 and ACAN.contents.FIdxChn == 0):
        # RollingCounter
        if Enable_0x3D9_RollingCounter_Error != True:
            a = ACAN.contents.FData[7] >> 4  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[7] = ((a << 4) & 0xF0) | (ACAN.contents.FData[7] & 0xF)
        else:
            ACAN.contents.FData[7] = 0 | (ACAN.contents.FData[7] & 0xF)


    if (ACAN.contents.FIdentifier == 0x121 and ACAN.contents.FIdxChn == 0):
        if Enable_0x121_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] & 0xF  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = (a & 0xF) | (ACAN.contents.FData[6] & 0xF0)
        else:
            ACAN.contents.FData[6] = 0
        # Checksum
        if Enable_0x121_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0


    if (ACAN.contents.FIdentifier == 0x1F0 and ACAN.contents.FIdxChn == 0):
        if Enable_0x1F0_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] >> 4  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = ((a << 4) & 0xF0) | (ACAN.contents.FData[6] & 0xF)
        else:
            ACAN.contents.FData[6] = 0 | (ACAN.contents.FData[6] & 0xF)
        # Checksum
        if Enable_0x1F0_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0

    if (ACAN.contents.FIdentifier == 0x220 and ACAN.contents.FIdxChn == 0):
        if Enable_0x220_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] & 0xF  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = (a & 0xF) | (ACAN.contents.FData[6] & 0xF0)
        else:
            ACAN.contents.FData[6] = 0 | (ACAN.contents.FData[6] & 0xF0)
            
        # Checksum
        if Enable_0x220_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0

    if (ACAN.contents.FIdentifier == 0x222 and ACAN.contents.FIdxChn == 0):
        if Enable_0x222_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] & 0xF  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = (a & 0xF) | (ACAN.contents.FData[6] & 0xF0)
        else:
            ACAN.contents.FData[6] = 0 | (ACAN.contents.FData[6] & 0xF0)
        # Checksum
        if Enable_0x222_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0

    if (ACAN.contents.FIdentifier == 0x223 and ACAN.contents.FIdxChn == 0):
        if Enable_0x223_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] & 0xF  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = (a & 0xF) | (ACAN.contents.FData[6] & 0xF0)
        else:
            ACAN.contents.FData[6] = 0 | (ACAN.contents.FData[6] & 0xF0)
        # Checksum
        if Enable_0x223_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0


    if (ACAN.contents.FIdentifier == 0x422 and ACAN.contents.FIdxChn == 0):
        if Enable_0x422_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] >> 4  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = ((a << 4) & 0xF0) | (ACAN.contents.FData[6] & 0xF)
        else:
            ACAN.contents.FData[6] = 0 | (ACAN.contents.FData[6] & 0xF)
        # Checksum
        if Enable_0x422_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0
        

    if (ACAN.contents.FIdentifier == 0x11F and ACAN.contents.FIdxChn == 0):
        if Enable_SAS_Scroll_Cycle_11F_Cnt_S_Error != True:
            a = ACAN.contents.FData[4] & 0xF  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[4] = (a & 0xF) | (ACAN.contents.FData[4] & 0xF0)
        else:
            ACAN.contents.FData[4] = 0 | (ACAN.contents.FData[4] & 0xF0)
        # Checksum
        if Enable_0x11F_Checksum_Error != True:
            temp_result = ACAN.contents.FData[0] ^ ACAN.contents.FData[1] ^ ACAN.contents.FData[2] ^ ACAN.contents.FData[3]
            check_sum = (temp_result >> 4) ^ (temp_result & 0xF) ^ (ACAN.contents.FData[4] & 0xF)
            ACAN.contents.FData[4] = ((check_sum << 4) & 0xF0) | (ACAN.contents.FData[4] & 0xF)
        else:
            ACAN.contents.FData[4] = 0 | (ACAN.contents.FData[4] & 0xF)


    if (ACAN.contents.FIdentifier == 0x342 and ACAN.contents.FIdxChn == 0):
        if Enable_0x342_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] >> 4  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = ((a << 4) & 0xF0) | (ACAN.contents.FData[6] & 0xF)
        else:
            ACAN.contents.FData[6] = 0 | (ACAN.contents.FData[6] & 0xF)
        # Checksum
        if Enable_0x342_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0


    if (ACAN.contents.FIdentifier == 0x134 and ACAN.contents.FIdxChn == 0):
        if Enable_0x134_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] >> 4  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = ((a << 4) & 0xF0) | (ACAN.contents.FData[6] & 0xF)
        else:
            ACAN.contents.FData[6] = 0 | (ACAN.contents.FData[6] & 0xF)
        # Checksum
        if Enable_0x134_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0

    if (ACAN.contents.FIdentifier == 0x195 and ACAN.contents.FIdxChn == 0):
        if Enable_0x195_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] >> 4  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = ((a << 4) & 0xF0) | (ACAN.contents.FData[6] & 0xF)
        else:
            ACAN.contents.FData[6] = 0 | (ACAN.contents.FData[6] & 0xF)
        # Checksum
        if Enable_0x195_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0

    if (ACAN.contents.FIdentifier == 0x1A7 and ACAN.contents.FIdxChn == 0):
        if Enable_0x1A7_RollingCounter_Error != True:
            a = ACAN.contents.FData[6] >> 4  # FData 字节数组int类型
            a += 1
            if a > 15:
                a = 0
            ACAN.contents.FData[6] = ((a << 4) & 0xF0) | (ACAN.contents.FData[6] & 0xF)
        else:
            ACAN.contents.FData[6] = 0 | (ACAN.contents.FData[6] & 0xF)
        # Checksum
        if Enable_0x1A7_Checksum_Error != True:
            ACAN.contents.FData[7] = sum(ACAN.contents.FData[0:7]) ^ 0xFF
        else:
            ACAN.contents.FData[7] = 0


    if (ACAN.contents.FIdentifier == 0x109 and ACAN.contents.FIdxChn == 0):
        if Enable_0x109_RollingCounter_Error != True:
            a = (ACAN.contents.FData[3]<<8) | ACAN.contents.FData[2]
            a += 1
            if a > 65535:
                a = 0
            packed_bytes = struct.pack('>H', a)
            ACAN.contents.FData[2] = packed_bytes[1]
            ACAN.contents.FData[3] = packed_bytes[0]
        else:
            ACAN.contents.FData[2] = 0
            ACAN.contents.FData[3] = 0
        # Checksum
        if Enable_0x109_Checksum_Error != True:
            crc16 = crc16_table(ACAN.contents.FData)
            packed_bytes = struct.pack('>H', crc16)
            ACAN.contents.FData[0] = packed_bytes[1]
            ACAN.contents.FData[1] = packed_bytes[0]
        else:
            ACAN.contents.FData[0] = 0
            ACAN.contents.FData[1] = 0


    if (ACAN.contents.FIdentifier == 0x258 and ACAN.contents.FIdxChn == 0):
        if Enable_0x258_RollingCounter_Error != True:
            a = (ACAN.contents.FData[3]<<8) | ACAN.contents.FData[2]
            a += 1
            if a > 65535:
                a = 0
            packed_bytes = struct.pack('>H', a)
            ACAN.contents.FData[2] = packed_bytes[1]
            ACAN.contents.FData[3] = packed_bytes[0]
        else:
            ACAN.contents.FData[2] = 0
            ACAN.contents.FData[3] = 0
        # Checksum
        if Enable_0x258_Checksum_Error != True:
            crc16 = crc16_table(ACAN.contents.FData)
            packed_bytes = struct.pack('>H', crc16)
            ACAN.contents.FData[0] = packed_bytes[1]
            ACAN.contents.FData[1] = packed_bytes[0]
        else:
            ACAN.contents.FData[0] = 0
            ACAN.contents.FData[1] = 0

    # if (ACAN.contents.FIdentifier == 0x2F6 and ACAN.contents.FIdxChn == 0):
    #     t = time.time()
    #     current = 0
    #     if (ACAN.contents.FData[0] == 0x20):
    #         current = int(t)
    #     if (ACAN.contents.FData[0] == 0x28):
    #         current = int(t % 1 * 1000000000)

    #     packed_bytes = struct.pack('i', current)
    #     ACAN.contents.FData[4] = packed_bytes[3]
    #     ACAN.contents.FData[5] = packed_bytes[2]
    #     ACAN.contents.FData[6] = packed_bytes[1]
    #     ACAN.contents.FData[7] = packed_bytes[0]

    #     if Enable_0x2F6_RollingCounter_Error != True:
    #         a = ACAN.contents.FData[2] & 0xF  # FData 字节数组int类型
    #         a += 1
    #         if a > 15:
    #             a = 0
    #         ACAN.contents.FData[2] = a | (ACAN.contents.FData[2] & 0xF0)
    #     else:
    #         ACAN.contents.FData[2] = 0 | (ACAN.contents.FData[2] & 0xF0)

    #     # CRC
    #     if Enable_0x2F6_CRC_Error != True:
    #         a = list(ACAN.contents.FData[0:9])
    #         a.pop(1)
    #         crc16 = Crc8_8H2F(a,8)
    #         ACAN.contents.FData[1] = crc16
    #     else:
    #         ACAN.contents.FData[1] = 0


def crc16_table(bytestr):
    '''
    crc16查表法
    :param bytestr: bytes字符串
    :return: int16类型
    '''
    crc = 0xFFFF
    data = bytearray(bytestr)
    len1 = len(bytestr)
    # logging.error('len:[{0}]'.format(len1))
    for i in range(2,len1):
        cp = (crc >> 8) ^ data[i]
        crc = ((crc << 8) & 0xFFFF) ^ mCRC16_Tables[cp]
    return crc

# CRC16 余式0x1021表
mCRC16_Tables=[ 0x0000,0x1021,0x2042,0x3063,0x4084,0x50A5,0x60C6,0x70E7,
                0x8108,0x9129,0xA14A,0xB16B,0xC18C,0xD1AD,0xE1CE,0xF1EF,
                0x1231,0x0210,0x3273,0x2252,0x52B5,0x4294,0x72F7,0x62D6,
                0x9339,0x8318,0xB37B,0xA35A,0xD3BD,0xC39C,0xF3FF,0xE3DE,
                0x2462,0x3443,0x0420,0x1401,0x64E6,0x74C7,0x44A4,0x5485,
                0xA56A,0xB54B,0x8528,0x9509,0xE5EE,0xF5CF,0xC5AC,0xD58D,
                0x3653,0x2672,0x1611,0x0630,0x76D7,0x66F6,0x5695,0x46B4,
                0xB75B,0xA77A,0x9719,0x8738,0xF7DF,0xE7FE,0xD79D,0xC7BC,
                0x48C4,0x58E5,0x6886,0x78A7,0x0840,0x1861,0x2802,0x3823,
                0xC9CC,0xD9ED,0xE98E,0xF9AF,0x8948,0x9969,0xA90A,0xB92B,
                0x5AF5,0x4AD4,0x7AB7,0x6A96,0x1A71,0x0A50,0x3A33,0x2A12,
                0xDBFD,0xCBDC,0xFBBF,0xEB9E,0x9B79,0x8B58,0xBB3B,0xAB1A,
                0x6CA6,0x7C87,0x4CE4,0x5CC5,0x2C22,0x3C03,0x0C60,0x1C41,
                0xEDAE,0xFD8F,0xCDEC,0xDDCD,0xAD2A,0xBD0B,0x8D68,0x9D49,
                0x7E97,0x6EB6,0x5ED5,0x4EF4,0x3E13,0x2E32,0x1E51,0x0E70,
                0xFF9F,0xEFBE,0xDFDD,0xCFFC,0xBF1B,0xAF3A,0x9F59,0x8F78,
                0x9188,0x81A9,0xB1CA,0xA1EB,0xD10C,0xC12D,0xF14E,0xE16F,
                0x1080,0x00A1,0x30C2,0x20E3,0x5004,0x4025,0x7046,0x6067,
                0x83B9,0x9398,0xA3FB,0xB3DA,0xC33D,0xD31C,0xE37F,0xF35E,
                0x02B1,0x1290,0x22F3,0x32D2,0x4235,0x5214,0x6277,0x7256,
                0xB5EA,0xA5CB,0x95A8,0x8589,0xF56E,0xE54F,0xD52C,0xC50D,
                0x34E2,0x24C3,0x14A0,0x0481,0x7466,0x6447,0x5424,0x4405,
                0xA7DB,0xB7FA,0x8799,0x97B8,0xE75F,0xF77E,0xC71D,0xD73C,
                0x26D3,0x36F2,0x0691,0x16B0,0x6657,0x7676,0x4615,0x5634,
                0xD94C,0xC96D,0xF90E,0xE92F,0x99C8,0x89E9,0xB98A,0xA9AB,
                0x5844,0x4865,0x7806,0x6827,0x18C0,0x08E1,0x3882,0x28A3,
                0xCB7D,0xDB5C,0xEB3F,0xFB1E,0x8BF9,0x9BD8,0xABBB,0xBB9A,
                0x4A75,0x5A54,0x6A37,0x7A16,0x0AF1,0x1AD0,0x2AB3,0x3A92,
                0xFD2E,0xED0F,0xDD6C,0xCD4D,0xBDAA,0xAD8B,0x9DE8,0x8DC9,
                0x7C26,0x6C07,0x5C64,0x4C45,0x3CA2,0x2C83,0x1CE0,0x0CC1,
                0xEF1F,0xFF3E,0xCF5D,0xDF7C,0xAF9B,0xBFBA,0x8FD9,0x9FF8,
                0x6E17,0x7E36,0x4E55,0x5E74,0x2E93,0x3EB2,0x0ED1,0x1EF0
            ]


    # if ((ACAN.contents.FIdentifier == 0x2B6) and (ACAN.contents.FIdxChn == 0)):
    #     if Enable_0x12D_RollingCounter_Error != True:
    #         i = datetime.datetime.now()
    #         ACAN.contents.FData[0] = i.year - 2000
    #         ACAN.contents.FData[1] = i.month
    #         ACAN.contents.FData[2] = i.day
    #         ACAN.contents.FData[3] = i.hour
    #         ACAN.contents.FData[4] = i.minute
    #         ACAN.contents.FData[5] = i.second
    #         ACAN.contents.FData[6] = (i.isocalendar()[1] & 0x0F) | (ACAN.contents.FData[6] & 0xF0)
    #     else:
    #         ACAN.contents.FData[0] = i.year - 2000
    #         ACAN.contents.FData[1] = i.month
    #         ACAN.contents.FData[2] = i.day
    #         ACAN.contents.FData[3] = i.hour
    #         ACAN.contents.FData[4] = i.minute
    #         ACAN.contents.FData[5] = 0
    #         ACAN.contents.FData[6] = 0


OnCANPreFDevent = TSMasterAPI.OnTx_RxFUNC_CANFD(On_CANFD_EVENT_Pre)


new_rolling_data = []
run_faule_count = 0
corrRespStr = ""

'''监控PCAN数据'''
def check_PCAN(OBJ, ACAN2):
    global new_rolling_data
    global run_faule_count
    global corrRespStr


    if ACAN2.contents.FIdxChn == 0 and ACAN2.contents.FIdentifier == Set_up.resID:
        if ACAN2.contents.FData[1:3] == [0x51,0x01] or ACAN2.contents.FData[1:3] == [0x50,0x02]:
            real_CAN.Reset_Setup_Pcanlist(True)
        if ACAN2.contents.FData[1:3] == [0x50,0x01]:
            Set_up.startCheck = True
            logging.info('收到5001,开始比对PCAN数据')

    if (ACAN2.contents.FIdxChn == 1): 
        if ACAN2.contents.FIdentifier == 0x66F:
            Set_up.MRR_0x66F_data.append(ACAN2.contents.FData[0:16])
            Set_up.MRR_0x66F_time.append(time.time() * 1000)

        if ACAN2.contents.FIdentifier == 0x5F0:
            if ACAN2.contents.FData[0:4] == Set_up.CTBoot:
                Set_up.MRR_0x5F0_data.append(ACAN2.contents.FData[0:16])
                corrRespStr = binascii.b2a_hex(bytearray(ACAN2.contents.FData[0:8]), ' ')
                logging.warning('--------------**********************收到0x5F0,设备重启了. [{0}]**********************-------------'.format(corrRespStr))

        if ACAN2.contents.FIdentifier in Set_up.PCAN_list.keys():
            if Set_up.startCheck == True:
                if (Set_up.PCAN_list[ACAN2.contents.FIdentifier][1]):
                    Set_up.PCAN_list[ACAN2.contents.FIdentifier][0] = ACAN2.contents.FData[6] & 0xF 
                    run_faule_count = 0
                    Set_up.PCAN_list[ACAN2.contents.FIdentifier][1] = False 
                else:
                    new_rolling_data = ACAN2.contents.FData[6] & 0xF
                    Set_up.PCAN_list[ACAN2.contents.FIdentifier][0] += 1
                    if Set_up.PCAN_list[ACAN2.contents.FIdentifier][0] > 15:
                        Set_up.PCAN_list[ACAN2.contents.FIdentifier][0] = 0

                    aliveCount = (Set_up.PCAN_list[ACAN2.contents.FIdentifier][0] == (new_rolling_data))
                    corrRespStr = binascii.b2a_hex(bytearray(ACAN2.contents.FData[0:8]), ' ')
                    if aliveCount:
                        # logging.info('[{0}] == [{1}]'.format(Set_up.PCAN_list[ACAN2.contents.FIdentifier][0],new_rolling_data))
                        pass
                    else:
                        run_faule_count += 1
                        # logging.error('PCAN data rceve---rolling_counter:[{0}] != [{1}]'.format(Set_up.PCAN_list[ACAN2.contents.FIdentifier][0],new_rolling_data))
                        Set_up.PCAN_list[ACAN2.contents.FIdentifier][2] += 1
                        # logging.error('PCAN data error---FailedCount[{0}]ID:[0x{1:X}], DATA:[{2}]'.format(Set_up.PCAN_list[ACAN2.contents.FIdentifier][2],ACAN2.contents.FIdentifier,corrRespStr))

                    crcSUM = Crc8_8H2F(ACAN2.contents.FData[0:8],8)
                    CheckSum = (crcSUM == (ACAN2.contents.FData[7]))
                    # logging.info("checkSum status: {0} {1} == {2}".format(CheckSum, crcSUM,ACAN2.contents.FData[7]))
                    if CheckSum:
                        pass
                    else:
                        run_faule_count += 1
                        Set_up.PCAN_list[ACAN2.contents.FIdentifier][2] += 1
                        # logging.error('PCAN CheckSum error---FailedCount[{0}]ID:[0x{1:X}], DATA:[{2}]'.format(Set_up.PCAN_list[ACAN2.contents.FIdentifier][2],ACAN2.contents.FIdentifier,corrRespStr))

        if ACAN2.contents.FIdentifier in Set_up.PCAN_list_BOCH.keys():
            if Set_up.startCheck == True:
                if (Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][1]):
                    Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][0] = (ACAN2.contents.FData[2]<<8) | ACAN2.contents.FData[1]
                    run_faule_count = 0
                    Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][1] = False 
                else:
                    datalen = Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][3]    

                    new_rolling_data = (ACAN2.contents.FData[2]<<8) | ACAN2.contents.FData[1]
                    Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][0] += 1
                    if Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][0] > 65535:
                        Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][0] = 0

                    aliveCount = (Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][0] == (new_rolling_data))
                    corrRespStr = binascii.b2a_hex(bytearray(ACAN2.contents.FData[0:datalen]), ' ')
                    if aliveCount:
                        pass
                    else:
                        run_faule_count += 1
                        Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][2] += 1
                        # logging.error('PCAN BOCH data error---FailedCount[{0}]ID:[0x{1:X}], DATA:[{2}]'.format(Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][2],ACAN2.contents.FIdentifier,corrRespStr))
                                     
                    crcSUM = (sum(ACAN2.contents.FData[1:datalen]) ^ 0xFF) & 0xFF 
                    CheckSum = (crcSUM == (ACAN2.contents.FData[0]))
                    if CheckSum:
                        pass
                    else:
                        run_faule_count += 1
                        Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][2] += 1
                        # logging.error('PCAN BOCH CheckSum error---FailedCount[{0}]ID:[0x{1:X}], DATA:[{2}]'.format(Set_up.PCAN_list_BOCH[ACAN2.contents.FIdentifier][2],ACAN2.contents.FIdentifier,corrRespStr))
            
        


OnCANPreFDevent_checkPCAN = TSMasterAPI.OnTx_RxFUNC_CANFD(check_PCAN)




'''CRC-8校验计算'''
# Crc8_8H2F 多项式0x12F
Crc8_8H2Ftable = [  0x00, 0x2F, 0x5E, 0x71, 0xBC, 0x93, 0xE2, 0xCD, 0x57, 0x78, 0x09, 0x26, 0xEB, 0xC4, 0xB5, 0x9A,
                    0xAE, 0x81, 0xF0, 0xDF, 0x12, 0x3D, 0x4C, 0x63, 0xF9, 0xD6, 0xA7, 0x88, 0x45, 0x6A, 0x1B, 0x34,
                    0x73, 0x5C, 0x2D, 0x02, 0xCF, 0xE0, 0x91, 0xBE, 0x24, 0x0B, 0x7A, 0x55, 0x98, 0xB7, 0xC6, 0xE9,
                    0xDD, 0xF2, 0x83, 0xAC, 0x61, 0x4E, 0x3F, 0x10, 0x8A, 0xA5, 0xD4, 0xFB, 0x36, 0x19, 0x68, 0x47,
                    0xE6, 0xC9, 0xB8, 0x97, 0x5A, 0x75, 0x04, 0x2B, 0xB1, 0x9E, 0xEF, 0xC0, 0x0D, 0x22, 0x53, 0x7C,
                    0x48, 0x67, 0x16, 0x39, 0xF4, 0xDB, 0xAA, 0x85, 0x1F, 0x30, 0x41, 0x6E, 0xA3, 0x8C, 0xFD, 0xD2,
                    0x95, 0xBA, 0xCB, 0xE4, 0x29, 0x06, 0x77, 0x58, 0xC2, 0xED, 0x9C, 0xB3, 0x7E, 0x51, 0x20, 0x0F,
                    0x3B, 0x14, 0x65, 0x4A, 0x87, 0xA8, 0xD9, 0xF6, 0x6C, 0x43, 0x32, 0x1D, 0xD0, 0xFF, 0x8E, 0xA1,
                    0xE3, 0xCC, 0xBD, 0x92, 0x5F, 0x70, 0x01, 0x2E, 0xB4, 0x9B, 0xEA, 0xC5, 0x08, 0x27, 0x56, 0x79,
                    0x4D, 0x62, 0x13, 0x3C, 0xF1, 0xDE, 0xAF, 0x80, 0x1A, 0x35, 0x44, 0x6B, 0xA6, 0x89, 0xF8, 0xD7,
                    0x90, 0xBF, 0xCE, 0xE1, 0x2C, 0x03, 0x72, 0x5D, 0xC7, 0xE8, 0x99, 0xB6, 0x7B, 0x54, 0x25, 0x0A,
                    0x3E, 0x11, 0x60, 0x4F, 0x82, 0xAD, 0xDC, 0xF3, 0x69, 0x46, 0x37, 0x18, 0xD5, 0xFA, 0x8B, 0xA4,
                    0x05, 0x2A, 0x5B, 0x74, 0xB9, 0x96, 0xE7, 0xC8, 0x52, 0x7D, 0x0C, 0x23, 0xEE, 0xC1, 0xB0, 0x9F,
                    0xAB, 0x84, 0xF5, 0xDA, 0x17, 0x38, 0x49, 0x66, 0xFC, 0xD3, 0xA2, 0x8D, 0x40, 0x6F, 0x1E, 0x31,
                    0x76, 0x59, 0x28, 0x07, 0xCA, 0xE5, 0x94, 0xBB, 0x21, 0x0E, 0x7F, 0x50, 0x9D, 0xB2, 0xC3, 0xEC,
                    0xD8, 0xF7, 0x86, 0xA9, 0x64, 0x4B, 0x3A, 0x15, 0x8F, 0xA0, 0xD1, 0xFE, 0x33, 0x1C, 0x6D, 0x42,
                ]

def Crc8_8H2F(pData,len):
    crc8 = 0xFF
    for i in range(len-1):
        crc8 ^= pData[i]
        crc8 = Crc8_8H2Ftable[crc8]
    #     logging.info("Crc8 = {0}".format(crc8))
    # crc8 ^= pData[0]
    # crc8 = Crc8_8H2Ftable[crc8]
    # logging.info("Crc8 = {0}".format(crc8))
    crc8 ^= 0xFF
    return crc8

# modbus = Modbus('COM8')


class real_CAN(TSCAN):
    #0x3D9
    # def set_0x2B6_rolling_counter_error(self,enable=False):
    #     global Enable_0x2B6_RollingCounter_Error
    #     if enable:
    #         Enable_0x2B6_RollingCounter_Error = True
    #     else:
    #         Enable_0x2B6_RollingCounter_Error = False

    #0x3D9
    def set_0x3D9_rolling_counter_error(self,enable=False):
        global Enable_0x3D9_RollingCounter_Error
        if enable:
            Enable_0x3D9_RollingCounter_Error = True
        else:
            Enable_0x3D9_RollingCounter_Error = False
    
    def set_0x3D9_checksum_error(self,enable=False):
        global Enable_0x3D9_Checksum_Error
        if enable:
            logging.info("Set 0x3D9 Checksum mistake")
            Enable_0x3D9_Checksum_Error = True
        else:
            logging.info("Set 0x3D9 Checksum correct")
            Enable_0x3D9_Checksum_Error = False 

    #0x12D
    def set_0x12D_rolling_counter_error(self,enable=False):
        global Enable_0x12D_RollingCounter_Error
        if enable:
            logging.info("Set 0x12D rolling counter mistake")
            Enable_0x12D_RollingCounter_Error = True
        else:
            Enable_0x12D_RollingCounter_Error = False
    
    def set_0x12D_checksum_error(self,enable=False):
        global Enable_0x12D_Checksum_Error
        if enable:
            logging.info("Set 0x12D Checksum mistake")
            Enable_0x12D_Checksum_Error = True
        else:
            logging.info("Set 0x12D Checksum correct")
            Enable_0x12D_Checksum_Error = False 

    #0x134
    def set_0x134_rolling_counter_error(self,enable=False):
        global Enable_0x134_RollingCounter_Error
        if enable:
            logging.info("Set 0x134 rolling counter mistake")
            Enable_0x134_RollingCounter_Error = True
        else:
            Enable_0x134_RollingCounter_Error = False

    def set_0x134_checksum_error(self,enable=False):
        global Enable_0x134_Checksum_Error
        if enable:
            logging.info("Set 0x134 Checksum mistake")
            Enable_0x134_Checksum_Error = True
        else:
            logging.info("Set 0x134 Checksum correct")
            Enable_0x134_Checksum_Error = False 

    #0x195
    def set_0x195_rolling_counter_error(self,enable=False):
        global Enable_0x195_RollingCounter_Error
        if enable:
            logging.info("Set 0x195 rolling counter mistake")
            Enable_0x195_RollingCounter_Error = True
        else:
            Enable_0x195_RollingCounter_Error = False

    def set_0x195_checksum_error(self,enable=False):
        global Enable_0x195_Checksum_Error
        if enable:
            logging.info("Set 0x195 Checksum mistake")
            Enable_0x195_Checksum_Error = True
        else:
            logging.info("Set 0x195 Checksum correct")
            Enable_0x195_Checksum_Error = False


    #0x1A7
    def set_0x1A7_rolling_counter_error(self,enable=False):
        global Enable_0x1A7_RollingCounter_Error
        if enable:
            logging.info("Set 0x1A7 rolling counter mistake")
            Enable_0x1A7_RollingCounter_Error = True
        else:
            Enable_0x1A7_RollingCounter_Error = False

    def set_0x1A7_checksum_error(self,enable=False):
        global Enable_0x1A7_Checksum_Error
        if enable:
            logging.info("Set 0x1A7 Checksum mistake")
            Enable_0x1A7_Checksum_Error = True
        else:
            logging.info("Set 0x1A7 Checksum correct")
            Enable_0x1A7_Checksum_Error = False


    #0x109
    def set_0x109_rolling_counter_error(self,enable=False):
        global Enable_0x109_RollingCounter_Error
        if enable:
            logging.info("Set 0x109 rolling counter mistake")
            Enable_0x109_RollingCounter_Error = True
        else:
            Enable_0x109_RollingCounter_Error = False

    def set_0x109_checksum_error(self,enable=False):
        global Enable_0x109_Checksum_Error
        if enable:
            logging.info("Set 0x109 Checksum mistake")
            Enable_0x109_Checksum_Error = True
        else:
            logging.info("Set 0x109 Checksum correct")
            Enable_0x109_Checksum_Error = False


    #0x258
    def set_0x258_rolling_counter_error(self,enable=False):
        global Enable_0x258_RollingCounter_Error
        if enable:
            logging.info("Set 0x258 rolling counter mistake")
            Enable_0x258_RollingCounter_Error = True
        else:
            Enable_0x258_RollingCounter_Error = False

    def set_0x258_checksum_error(self,enable=False):
        global Enable_0x258_Checksum_Error
        if enable:
            logging.info("Set 0x258 Checksum mistake")
            Enable_0x258_Checksum_Error = True
        else:
            logging.info("Set 0x258 Checksum correct")
            Enable_0x258_Checksum_Error = False

    def Enable_0x2F6_CRC_Error(self,enable=False):
        global Enable_0x2F6_CRC_Error
        if enable:
            logging.info("Set 0x2F6 CRC mistake")
            Enable_0x2F6_CRC_Error = True
        else:
            logging.info("Set 0x2F6 CRC correct")
            Enable_0x2F6_CRC_Error = False

    def set_0x2F6_rolling_counter_error(self,enable=False):
        global Enable_0x2F6_RollingCounter_Error
        if enable:
            logging.info("Set 0x2F6 rolling counter mistake")
            Enable_0x2F6_RollingCounter_Error = True
        else:
            Enable_0x2F6_RollingCounter_Error = False

    # #0x294
    # def set_0x294_rolling_counter_error(self,enable=False):
    #     global Enable_0x294_RollingCounter_Error
    #     if enable:
    #         Enable_0x294_RollingCounter_Error = True
    #     else:
    #         Enable_0x294_RollingCounter_Error = False
    
    # def set_0x294_checksum_error(self,enable=False):
    #     global Enable_0x294_Checksum_Error
    #     if enable:
    #         Enable_0x294_Checksum_Error = True
    #     else:
    #         Enable_0x294_Checksum_Error = False 
    
    #0x121
    def set_0x121_rolling_counter_error(self,enable=False):
        global Enable_0x121_RollingCounter_Error
        if enable:
            Enable_0x121_RollingCounter_Error = True
        else:
            Enable_0x121_RollingCounter_Error = False
    
    def set_0x121_checksum_error(self,enable=False):
        global Enable_0x121_Checksum_Error
        if enable:
            logging.info("Set 0x121 Checksum mistake")
            Enable_0x121_Checksum_Error = True
        else:
            logging.info("Set 0x121 Checksum correct")
            Enable_0x121_Checksum_Error = False

    # 0x240
    def set_0x240_rolling_counter_error(self,enable=False):
        global Enable_0x240_RollingCounter_Error
        if enable:
            Enable_0x240_RollingCounter_Error = True
        else:
            Enable_0x240_RollingCounter_Error = False
    
    def set_0x240_checksum_error(self,enable=False):
        global Enable_0x240_Checksum_Error
        if enable:
            logging.info("Set 0x240 Checksum mistake")
            Enable_0x240_Checksum_Error = True
        else:
            logging.info("Set 0x240 Checksum correct")
            Enable_0x240_Checksum_Error = False

    #0x242
    def set_0x242_rolling_counter_error(self,enable=False):
        global Enable_0x242_RollingCounter_Error
        if enable:
            Enable_0x242_RollingCounter_Error = True
        else:
            Enable_0x242_RollingCounter_Error = False
    
    def set_0x242_checksum_error(self,enable=False):
        global Enable_0x242_Checksum_Error
        if enable:
            logging.info("Set 0x242 Checksum mistake")
            Enable_0x242_Checksum_Error = True
        else:
            logging.info("Set 0x242 Checksum correct")
            Enable_0x242_Checksum_Error = False 
    
    #0x341
    def set_0x341_rolling_counter_error(self,enable=False):
        global Enable_0x341_RollingCounter_Error
        if enable:
            Enable_0x341_RollingCounter_Error = True
        else:
            Enable_0x341_RollingCounter_Error = False
    
    def set_0x341_checksum_error(self,enable=False):
        global Enable_0x341_Checksum_Error
        if enable:
            logging.info("Set 0x341 Checksum mistake")
            Enable_0x341_Checksum_Error = True
        else:
            logging.info("Set 0x341 Checksum correct")
            Enable_0x341_Checksum_Error = False 


    #0x342
    def set_0x342_rolling_counter_error(self,enable=False):
        global Enable_0x342_RollingCounter_Error
        if enable:
            Enable_0x342_RollingCounter_Error = True
        else:
            Enable_0x342_RollingCounter_Error = False
    
    def set_0x342_checksum_error(self,enable=False):
        global Enable_0x342_Checksum_Error
        if enable:
            logging.info("Set 0x342 Checksum mistake")
            Enable_0x342_Checksum_Error = True
        else:
            logging.info("Set 0x342 Checksum correct")
            Enable_0x342_Checksum_Error = False 
    
    #0x123
    def set_0x123_rolling_counter_error(self,enable=False):
        global Enable_0x123_RollingCounter_Error
        if enable:
            Enable_0x123_RollingCounter_Error = True
        else:
            Enable_0x123_RollingCounter_Error = False
    
    def set_0x123_checksum_error(self,enable=False):
        global Enable_0x123_Checksum_Error
        if enable:
            logging.info("Set 0x123 Checksum mistake")
            Enable_0x123_Checksum_Error = True
        else:
            logging.info("Set 0x123 Checksum correct")
            Enable_0x123_Checksum_Error = False 

    #0x1F0
    def set_0x1F0_rolling_counter_error(self,enable=False):
        global Enable_0x1F0_RollingCounter_Error
        if enable:
            Enable_0x1F0_RollingCounter_Error = True
        else:
            Enable_0x1F0_RollingCounter_Error = False
    
    def set_0x1F0_checksum_error(self,enable=False):
        global Enable_0x1F0_Checksum_Error
        if enable:
            logging.info("Set 0x1F0 Checksum mistake")
            Enable_0x1F0_Checksum_Error = True
        else:
            logging.info("Set 0x1F0 Checksum correct")
            Enable_0x1F0_Checksum_Error = False 

    #0x220
    def set_0x220_rolling_counter_error(self,enable=False):
        global Enable_0x220_RollingCounter_Error
        if enable:
            Enable_0x220_RollingCounter_Error = True
        else:
            Enable_0x220_RollingCounter_Error = False
    
    def set_0x220_checksum_error(self,enable=False):
        global Enable_0x220_Checksum_Error
        if enable:
            logging.info("Set 0x220 Checksum mistake")
            Enable_0x220_Checksum_Error = True
        else:
            logging.info("Set 0x220 Checksum correct")
            Enable_0x220_Checksum_Error = False 

    #0x222
    def set_0x222_rolling_counter_error(self,enable=False):
        global Enable_0x222_RollingCounter_Error
        if enable:
            Enable_0x222_RollingCounter_Error = True
        else:
            Enable_0x222_RollingCounter_Error = False
    
    def set_0x222_checksum_error(self,enable=False):
        global Enable_0x222_Checksum_Error
        if enable:
            logging.info("Set 0x222 Checksum mistake")
            Enable_0x222_Checksum_Error = True
        else:
            logging.info("Set 0x222 Checksum correct")
            Enable_0x222_Checksum_Error = False 


    #0x223
    def set_0x223_rolling_counter_error(self,enable=False):
        global Enable_0x223_RollingCounter_Error
        if enable:
            Enable_0x223_RollingCounter_Error = True
        else:
            Enable_0x223_RollingCounter_Error = False
    
    def set_0x223_checksum_error(self,enable=False):
        global Enable_0x223_Checksum_Error
        if enable:
            logging.info("Set 0x223 Checksum mistake")
            Enable_0x223_Checksum_Error = True
        else:
            logging.info("Set 0x223 Checksum correct")
            Enable_0x223_Checksum_Error = False 

    #0x321
    def set_0x321_rolling_counter_error(self,enable=False):
        global Enable_0x321_RollingCounter_Error
        if enable:
            Enable_0x321_RollingCounter_Error = True
        else:
            Enable_0x321_RollingCounter_Error = False
    
    def set_0x321_checksum_error(self,enable=False):
        global Enable_0x321_Checksum_Error
        if enable:
            logging.info("Set 0x321 Checksum mistake")
            Enable_0x321_Checksum_Error = True
        else:
            logging.info("Set 0x321 Checksum correct")
            Enable_0x321_Checksum_Error = False 

    #0x422
    def set_0x422_rolling_counter_error(self,enable=False):
        global Enable_0x422_RollingCounter_Error
        if enable:
            Enable_0x422_RollingCounter_Error = True
        else:
            Enable_0x422_RollingCounter_Error = False
    
    def set_0x422_checksum_error(self,enable=False):
        global Enable_0x422_Checksum_Error
        if enable:
            logging.info("Set 0x422 Checksum mistake")
            Enable_0x422_Checksum_Error = True
        else:
            logging.info("Set 0x422 Checksum correct")
            Enable_0x422_Checksum_Error = False 


    #0x1FC
    def set_0x1FC_rolling_counter_error(self,enable=False):
        global Enable_0x1FC_RollingCounter_Error
        if enable:
            Enable_0x1FC_RollingCounter_Error = True
        else:
            Enable_0x1FC_RollingCounter_Error = False
    
    def set_0x1FC_checksum_error(self,enable=False):
        global Enable_0x1FC_Checksum_Error
        if enable:
            logging.info("Set 0x1FC Checksum mistake")
            Enable_0x1FC_Checksum_Error = True
        else:
            logging.info("Set 0x1FC Checksum correct")
            Enable_0x1FC_Checksum_Error = False 

    #0x24C
    def set_0x24C_rolling_counter_error(self,enable=False):
        global Enable_0x24C_RollingCounter_Error
        if enable:
            Enable_0x24C_RollingCounter_Error = True
        else:
            Enable_0x24C_RollingCounter_Error = False
    
    def set_0x24C_checksum_error(self,enable=False):
        global Enable_0x24C_Checksum_Error
        if enable:
            logging.info("Set 0x24C Checksum mistake")
            Enable_0x24C_Checksum_Error = True
        else:
            logging.info("Set 0x24C Checksum correct")
            Enable_0x24C_Checksum_Error = False


    #0x11F
    def set_0x11F_rolling_counter_error(self,enable=False):
        global Enable_SAS_Scroll_Cycle_11F_Cnt_S_Error
        if enable:
            Enable_SAS_Scroll_Cycle_11F_Cnt_S_Error = True
        else:
            Enable_SAS_Scroll_Cycle_11F_Cnt_S_Error = False
    
    def set_0x11F_checksum_error(self,enable=False):
        global Enable_0x11F_Checksum_Error
        if enable:
            logging.info("Set 0x11F Checksum mistake")
            Enable_0x11F_Checksum_Error = True
        else:
            logging.info("Set 0x11F Checksum correct")
            Enable_0x11F_Checksum_Error = False 

    
    def calcKey(self,seed):
        TOPBIT = 0x8000
        POLYMON_1 = 0x8408   
        POLYNOM_2 = 0x8025
        BITMASK  = 0x0080
        INITIAL_REMINDER = 0xFFFE
        MSG_LEN = 2 #seed length in bytes
        bSeed = [0,0]
        remainder = INITIAL_REMINDER
        bSeed[0] = seed[0]  #MSB
        bSeed[1] = seed[1] #LSB
        key = [0,0]

        for n in range(MSG_LEN):
            remainder ^= ((bSeed[n]&0xFF) << 8)
            for i in range(8):
                if (remainder & TOPBIT):
                    if(remainder & BITMASK):
                        remainder = (remainder << 1) ^ POLYMON_1
                    else:
                        remainder = (remainder << 1) ^ POLYNOM_2
                else:
                    remainder = (remainder << 1)
        key[0] = (remainder&0xFFFF)>>8
        key[1] = remainder&0xFF
        logging.info(key)
        return key

    '''BYD密钥计算'''
    def byd_calcKey(self,seed):
        KeyKValue = 0x0094
        key = [0,0,0,0]

        iSeed = seed[0] << 24|seed[1] << 16|seed[2] << 8 |seed[3]
        KeyResult = ((((iSeed >> 1) ^ iSeed) << 3) ^ (iSeed >> 2))
        STccKey = KeyResult ^ KeyKValue
        key[0] = (STccKey>>24) &0xFF
        key[1] = (STccKey>>16) &0xFF
        key[2] = (STccKey>>8) &0xFF
        key[3] = STccKey &0xFF
        return key

    '''设置信号使能状态'''
    def setSignalEanble(self, message, status, waitTime, iStep):
        if status == False:
            with allure.step(f'Step{iStep}: Create fault of the message {message} lost'):
                self.Enable_rbs_message(Set_up.NetName,Set_up.nodeName, message, False) 
        else:
            with allure.step(f'Step{iStep}: recover fault of the message {message} losted'):
                self.Enable_rbs_message(Set_up.NetName,Set_up.nodeName, message, True)
        logging.info(f'wait {waitTime} s') 
        time.sleep(waitTime)
        iStep += 1
        return iStep

    '''设置信号值'''
    def setSignalValue(Self, message, signal, value, iStep):
        with allure.step(f'Step{iStep}: set the value of the {signal} in {message} to {value}'):
            Self.write_db_signal(Set_up.NetName,Set_up.nodeName, message, signal, value)
            time.sleep(0.5)
            iStep += 1
            readValue = Self.read_db_signal(Set_up.NetName,Set_up.nodeName, message, signal)
        with allure.step(f'Step{iStep}: Read the value of the {signal} in {message} is {readValue}'):
            iStep += 1
        return iStep

    '''转换字符串为数组'''
    def strToToHexBytes(self,hexString):
        hexString = str(hexString).replace(' ', '').replace('[', '').replace(']', '').replace('\'', '')

        if ((len(hexString) % 2) != 0):
            hexString += " "

        c_16_temp = list(hexString)
        ilen = int(len(c_16_temp) / 2)
        hexBytes = [0] * ilen
        for index in range(ilen):
            hexBytes[index] = int((c_16_temp[2 * index] + c_16_temp[2 * index + 1]),16)
        return hexBytes
   
    def unlock(self,Driver, iStep):
        try:
            seed = []
            with allure.step(f"Step{iStep}:Request:0x27 0x01 # Response:0x67,0x01 xx xx xx xx"):
                uds_rep,size = Driver['UDS'].req_and_res_can([0x27,0x01],2)
                with assume: assert (uds_rep[0:2] == [0x67,0x01] and size == 6)
                for i in range(4):
                    if size == 6:
                        seed.append(uds_rep[2+i])
                    else:
                        seed.append(0)
            
                key = Driver['CAN'].byd_calcKey(seed)
                send_key = [0x27,0x02] + key

            iStep = iStep + 1
            with allure.step(f"Step{iStep}:Request:{0} # Response:0x67,0x02".format(binascii.b2a_hex(bytearray(send_key), ' '))):
                uds_rep,size = Driver['UDS'].req_and_res_can(send_key,6)
                with assume: assert uds_rep[0:2] == [0x67,0x02]
            
            return iStep + 1
        except Exception as e:
            logging.info(f"{e}".center(50, '-'))

    ''' Reqstr=发送信息 Respstr=接收信息 session=会话模式 iStep=步骤几 unlock=会话模式切换完成是否需要安全认证'''
    def checkReqResp(self, Driver, Reqstr, Respstr, session, iStep, unlock=False, addressing='UDS', isClearFault='noClearFault'):

        # 判断传入变量类型
        if isinstance(Reqstr, str):
            req = self.strToToHexBytes(Reqstr)
        else:
            req = Reqstr
        if isinstance(Respstr, str):
            resp = self.strToToHexBytes(Respstr)
        else:
            resp = Respstr

        # 会话模式
        if session==1 or session==3 or session == 2:
            with allure.step(f'Step{iStep}: Request 0x10 0x01 # Response: 0x50,0x01'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x10, 0x01], 2)
                with assume:uds_resp[0:2] == [0x50, 0x01]
                iStep = iStep + 1
                time.sleep(1)
            with allure.step(f'Step{iStep}: Request 0x22 0xF1 0x86 # Response: 0x62,0xF1,0x86 0x01'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x22, 0xF1, 0x86], 3)
                with assume: assert uds_resp[0:4] == [0x62,0xF1,0x86, 0x01]
                iStep = iStep + 1
        if session == 3 or session == 2:
            with allure.step(f'Step{iStep}: Request 0x10 0x03 # Response: 0x50,0x03'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x10, 0x03], 2)
                with assume:uds_resp[0:2] == [0x50, 0x03]
                iStep = iStep + 1
                time.sleep(1)
            with allure.step(f'Step{iStep}: Request 0x22 0xF1 0x86 # Response: 0x62,0xF1,0x86 0x03'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x22, 0xF1, 0x86], 3)
                with assume: assert uds_resp[0:4] == [0x62,0xF1,0x86, 0x03]
                iStep = iStep + 1
        if session==2:
            iStep = self.unlock(Driver,iStep)
            with allure.step(f'Step{iStep}: Request 0x10 0x02 # Response: 0x50,0x02'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x10, 0x02], 2)
                with assume:uds_resp[0:2] == [0x50, 0x02]
                iStep = iStep + 1
                time.sleep(2)
            with allure.step(f'Step{iStep}: Request 0x22 0xF1 0x86 # Response: 0x62,0xF1,0x86 0x02'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x22, 0xF1, 0x86], 3)
                with assume: assert uds_resp[0:4] == [0x62,0xF1,0x86, 0x02]
                iStep = iStep + 1
        if unlock:
            iStep = self.unlock(Driver,iStep)

        '''清除故障''' 
        if isClearFault != 'noClearFault':
            with allure.step(f"Step{iStep}:Request 0x14 0xFF 0xFF 0xFF # Response: 0x54"):
                uds_rep, size = Driver['UDS'].req_and_res_can([0x14, 0xFF, 0xFF, 0xFF], 4)
                iStep +=1 
                reqstr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                with assume: assert uds_rep[0] == 0x54
                iStep +=1 
                time.sleep(2)

        reqstr = binascii.b2a_hex(bytearray(req), ' ')
        respstr = binascii.b2a_hex(bytearray(resp), ' ')
        
        with allure.step(f'Step{iStep}: Request {reqstr} # Response: {respstr}'): 
            uds_resp, size = Driver[addressing].req_and_res_can(req, len(req))

            if len(resp) > 2 and len(uds_resp) > 2:
                if uds_resp[0] == 0x7F and uds_resp[2] == 0x22 and resp[0] != uds_resp[0]:
                    uds_resp2, size2 = Driver['UDS'].req_and_res_can([0x22, 0x02, 0x85], 3)
                    vspeed = self.read_db_signal(Set_up.NetName,Set_up.nodeName, 'IPB_0x121','IPB_Vehicle_Speed_S')
                    logging.warning('volt = [{0}], vspeed = [{1}]'.format(uds_resp2[3] / 10, vspeed))

            if len(resp) == 0 :
                with assume: assert 0 == size
            elif len(uds_resp) == 0:
                with assume: len(resp) == size
                corrRespStr = binascii.b2a_hex(bytearray(resp), ' ')
                actuRespStr = binascii.b2a_hex(bytearray(uds_resp[0:len(uds_resp)]), ' ')   
                logging.error(f'correct response:[{corrRespStr}], actual response:[{actuRespStr}]') 
            else:    
                if uds_resp[0:len(resp)] != resp:
                    corrRespStr = binascii.b2a_hex(bytearray(resp), ' ')
                    actuRespStr = binascii.b2a_hex(bytearray(uds_resp[0:len(uds_resp)]), ' ')   
                    logging.error(f'correct response:[{corrRespStr}], actual response:[{actuRespStr}]')  
                with assume: 
                    assert uds_resp[0:len(resp)] == resp
                    if req == [0x27,0x01] and resp[0] != 0x7F:
                        assert size == 6

        return iStep + 1,uds_resp, size


    
    def checkReqRespNoWait(self, Driver, Reqstr, Respstr, session, iStep=1, unlock=False, addressing='UDS', isClearFault='noClearFault'):
        """
        检测发送与接收是否符合预期函数，会话切换无等待时间.
        Parameters:
            Driver - Driver. 
            Reqstr - 请求信息
            Respstr - 期待返回信息  
            session - 会话模式  
            iStep - 第几步,默认为步骤1. 
            unlock - 是否安全解锁,默认不安全解锁 
            addressing - 寻址方式，默认物理寻址 
            isClearFault - 是否清除故障,默认不清除    

        Returns:
            iStep - 第几步
            uds_resp - 返回信息 
            size - 信息长度
        """

        # 判断传入变量类型
        if isinstance(Reqstr, str):
            req = self.strToToHexBytes(Reqstr)
        else:
            req = Reqstr
        if isinstance(Respstr, str):
            resp = self.strToToHexBytes(Respstr)
        else:
            resp = Respstr

        # 会话模式
        if session==1 or session==3 or session == 2:
            with allure.step(f'Step{iStep}: Request 0x10 0x01 # Response: 0x50,0x01'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x10, 0x01], 2)
                with assume:uds_resp[0:2] == [0x50, 0x01]
                iStep = iStep + 1
            with allure.step(f'Step{iStep}: Request 0x22 0xF1 0x86 # Response: 0x62,0xF1,0x86 0x01'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x22, 0xF1, 0x86], 3)
                with assume: assert uds_resp[0:4] == [0x62,0xF1,0x86, 0x01]
                iStep = iStep + 1
        if session == 3 or session == 2:
            with allure.step(f'Step{iStep}: Request 0x10 0x03 # Response: 0x50,0x03'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x10, 0x03], 2)
                with assume:uds_resp[0:2] == [0x50, 0x03]
                time.sleep(0.5)
                iStep = iStep + 1
            with allure.step(f'Step{iStep}: Request 0x22 0xF1 0x86 # Response: 0x62,0xF1,0x86 0x03'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x22, 0xF1, 0x86], 3)
                with assume: assert uds_resp[0:4] == [0x62,0xF1,0x86, 0x03]
                iStep = iStep + 1
        if session==2:
            iStep = self.unlock(Driver,iStep)
            with allure.step(f'Step{iStep}: Request 0x10 0x02 # Response: 0x50,0x02'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x10, 0x02], 2)
                with assume:uds_resp[0:2] == [0x50, 0x02]
                time.sleep(1)
                iStep = iStep + 1
            with allure.step(f'Step{iStep}: Request 0x22 0xF1 0x86 # Response: 0x62,0xF1,0x86 0x02'):
                uds_resp, size = Driver['UDS'].req_and_res_can([0x22, 0xF1, 0x86], 3)
                with assume: assert uds_resp[0:4] == [0x62,0xF1,0x86, 0x02]
                iStep = iStep + 1
        if unlock:
            iStep = self.unlock(Driver,iStep)

        '''清除故障''' 
        if isClearFault != 'noClearFault':
            with allure.step(f"Step{iStep}:Request 0x14 0xFF 0xFF 0xFF # Response: 0x54"):
                uds_rep, size = Driver['UDS'].req_and_res_can([0x14, 0xFF, 0xFF, 0xFF], 4)
                iStep +=1 
                reqstr = binascii.b2a_hex(bytearray(uds_rep), ' ')
                with assume: assert uds_rep[0] == 0x54
                iStep +=1 
                time.sleep(2)
                
        reqstr = binascii.b2a_hex(bytearray(req), ' ')
        respstr = binascii.b2a_hex(bytearray(resp), ' ')
        
        with allure.step(f'Step{iStep}: Request {reqstr} # Response: {respstr}'): 
            uds_resp, size = Driver[addressing].req_and_res_can(req, len(req))

            if len(resp) > 2 and len(uds_resp) > 2:
                if uds_resp[0] == 0x7F and uds_resp[2] == 0x22 and resp[0] != uds_resp[0]:
                    uds_resp2, size2 = Driver['UDS'].req_and_res_can([0x22, 0x02, 0x85], 3)
                    vspeed = self.read_db_signal(Set_up.NetName,Set_up.nodeName, 'IPB_0x121','IPB_Vehicle_Speed_S')
                    logging.warning('volt = [{0}], vspeed = [{1}]'.format(uds_resp2[3] / 10, vspeed))

            if len(resp) == 0 :
                with assume: assert 0 == size
            elif len(uds_resp) == 0:
                with assume: len(resp) == size
                corrRespStr = binascii.b2a_hex(bytearray(resp), ' ')
                actuRespStr = binascii.b2a_hex(bytearray(uds_resp[0:len(uds_resp)]), ' ')   
                logging.error(f'correct response:[{corrRespStr}], actual response:[{actuRespStr}]') 
            else:    
                if uds_resp[0:len(resp)] != resp:
                    corrRespStr = binascii.b2a_hex(bytearray(resp), ' ')
                    actuRespStr = binascii.b2a_hex(bytearray(uds_resp[0:len(uds_resp)]), ' ')   
                    logging.error(f'correct response:[{corrRespStr}], actual response:[{actuRespStr}]')  
                with assume: 
                    assert uds_resp[0:len(resp)] == resp
                    if req == [0x27,0x01] and resp[0] != 0x7F:
                        assert size == 6

        return iStep + 1,uds_resp, size


    '''设置电源电压'''
    def SetVolt(self, Driver, VoltNumber, waitTime, iStep):
        with allure.step(f"Step{iStep}:Set voltage = {VoltNumber}V"):
            Driver['power'].set_vltage(VoltNumber)
        iStep += 1
        time.sleep(waitTime)
        Driver['power'].Read_Measure()
        return iStep

    def DTC_Left_BCM_TIMEOUT(self, iStep, Enable=False):
        cycleTime = 1000
        missCount = 5
        recoverCount = 1

        if Enable:
            waitTime = cycleTime * missCount/1000 + 0.200
            logging.info(f'停发Left_BCM_0x3D9,并等待{waitTime}s, 制造DTC_Left_BCM_TIMEOUT故障') 
            iStep = self.setSignalEanble('Left_BCM_0x3D9', False, waitTime, iStep)
        else:  
            waitTime = cycleTime * recoverCount/1000 + 0.2     
            logging.info(f'发送Left_BCM_0x3D9,并等待{waitTime}s, 恢复DTC_Left_BCM_TIMEOUT故障') 
            iStep = self.setSignalEanble('Left_BCM_0x3D9', True, waitTime, iStep)
        return iStep

    def DTC_Media_TIMEOUT(self, iStep, Enable=False):
        cycleTime = 500
        missCount = 5
        recoverCount = 1

        if Enable:
            waitTime = cycleTime * (missCount+1)/1000 + 0.1
            logging.info(f'停发Media_0x2B6,并等待{waitTime}s, 制造DTC_Media_TIMEOUT故障') 
            iStep = self.setSignalEanble('Media_0x2B6', False, waitTime, iStep)
        else:  
            waitTime = cycleTime * (recoverCount+1)/1000 + 0.1     
            logging.info(f'发送Media_0x2B6,并等待{waitTime}s, 恢复DTC_Media_TIMEOUT故障') 
            iStep = self.setSignalEanble('Media_0x2B6', True, waitTime, iStep)
        return iStep

    def DTC_VCU_TIMEOUT(self, iStep, Enable=False):
        cycleTime = 20
        missCount = 10
        recoverCount = 1

        if Enable:
            waitTime = cycleTime * (missCount+1)/1000+ 0.1 
            logging.info(f'停发VCU_0x342,并等待{waitTime}s, 制造DTC_VCU_TIMEOUT故障') 
            iStep = self.setSignalEanble('VCU_0x342', False, waitTime, iStep)
        else:  
            waitTime = cycleTime * (recoverCount+1)/1000  + 0.1    
            logging.info(f'发送VCU_0x342,并等待{waitTime}s, 恢复DTC_VCU_TIMEOUT故障') 
            iStep = self.setSignalEanble('VCU_0x342', True, waitTime, iStep)
        return iStep

    def DTC_IPB_TIMEOUT_IPB121(self, iStep, Enable=False):
        cycleTime = 20
        missCount = 10
        recoverCount = 1
        message = 'IPB_0x121'

        if Enable:
            waitTime = cycleTime * (missCount+1)/1000+ 0.1 
            logging.info(f'停发{message},并等待{waitTime}s, 制造DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, False, waitTime, iStep)
        else:  
            waitTime = cycleTime * (recoverCount+1)/1000 + 0.1     
            logging.info(f'发送{message},并等待{waitTime}s, 恢复DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, True, waitTime, iStep)
        return iStep

    def DTC_IPB_TIMEOUT_IPB1F0(self, iStep, Enable=False):
        cycleTime = 20
        missCount = 10
        recoverCount = 1
        message = 'IPB_0x1F0'

        if Enable:
            waitTime = cycleTime * (missCount+1)/1000+ 0.1 
            logging.info(f'停发{message},并等待{waitTime}s, 制造DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, False, waitTime, iStep)
        else:  
            waitTime = cycleTime * (recoverCount+1)/1000  + 0.1    
            logging.info(f'发送{message},并等待{waitTime}s, 恢复DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, True, waitTime, iStep)
        return iStep

    def DTC_IPB_TIMEOUT_IPB220(self, iStep, Enable=False):
        cycleTime = 20
        missCount = 10
        recoverCount = 1
        message = 'IPB_0x220'

        if Enable:
            waitTime = cycleTime * (missCount+1)/1000+ 0.1 
            logging.info(f'停发{message},并等待{waitTime}s, 制造DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, False, waitTime, iStep)
        else:  
            waitTime = cycleTime * (recoverCount+1)/1000 + 0.1     
            logging.info(f'发送{message},并等待{waitTime}s, 恢复DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, True, waitTime, iStep)
        return iStep

    def DTC_IPB_TIMEOUT_IPB222(self, iStep, Enable=False):
        cycleTime = 20
        missCount = 10
        recoverCount = 1
        message = 'IPB_0x222'

        if Enable:
            waitTime = cycleTime * (missCount+1)/1000+ 0.1 
            logging.info(f'停发{message},并等待{waitTime}s, 制造DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, False, waitTime, iStep)
        else:  
            waitTime = cycleTime * (recoverCount+1)/1000  + 0.1    
            logging.info(f'发送{message},并等待{waitTime}s, 恢复DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, True, waitTime, iStep)
        return iStep

    def DTC_IPB_TIMEOUT_IPB223(self, iStep, Enable=False):
        cycleTime = 20
        missCount = 10
        recoverCount = 1
        message = 'IPB_0x223'

        if Enable:
            waitTime = cycleTime * (missCount+1)/1000+ 0.1 
            logging.info(f'停发{message},并等待{waitTime}s, 制造DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble( message, False, waitTime, iStep)
        else:  
            waitTime = cycleTime * (recoverCount+1)/1000  + 0.1    
            logging.info(f'发送{message},并等待{waitTime}s, 恢复DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble( message, True, waitTime, iStep)
        return iStep

    def DTC_IPB_TIMEOUT_IPB422(self, iStep, Enable=False):
        cycleTime = 20
        missCount = 10
        recoverCount = 1
        message = 'IPB_0x422'

        if Enable:
            waitTime = cycleTime * (missCount+1)/1000+ 0.1 
            logging.info(f'停发{message},并等待{waitTime}s, 制造DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, False, waitTime, iStep)
        else:  
            waitTime = cycleTime * (recoverCount+1)/1000  + 0.1    
            logging.info(f'发送{message},并等待{waitTime}s, 恢复DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, True, waitTime, iStep)
        return iStep
    
    def DTC_EPS_TIMEOUT(self, iStep, Enable=False):
        cycleTime = 10
        missCount = 10
        recoverCount = 1
        message = 'EPS_0x11F'

        if Enable:
            waitTime = cycleTime * (missCount+1)/1000+ 0.1 
            logging.info(f'停发{message},并等待{waitTime}s, 制造DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, False, waitTime, iStep)
        else:  
            waitTime = cycleTime * (recoverCount+1)/1000  + 0.1    
            logging.info(f'发送{message},并等待{waitTime}s, 恢复DTC_IPB_TIMEOUT故障') 
            iStep = self.setSignalEanble(message, True, waitTime, iStep)
        return iStep

    def V_ConnectCanH_GND(self, Eanble,iStep):
        modbus = Modbus(Set_up.modbusCOM)
        if Eanble:
            self.Reset_Setup_Pcanlist(True)
            with allure.step(f"Step{iStep}:VCANH connects to VCANL"):
                modbus.write_single_coil(DO_Address_single.Y0.value,0x0001)
                time.sleep(6)
        else:
            with allure.step(f"Step{iStep}:Remove fault of VCANH connnects to VCANL"):
                modbus.write_single_coil(DO_Address_single.Y0.value,0x0000)
            time.sleep(1)
        iStep += 1
        del modbus

        return iStep

    def V_ConnectCanL_Vcc(self, Eanble,iStep):
        
        modbus = Modbus(Set_up.modbusCOM)
        if Eanble:
            self.Reset_Setup_Pcanlist(True)
            with allure.step(f"Step{iStep}:VCANH connects to VCANL"):
                modbus.write_single_coil(DO_Address_single.Y1.value,0x0001)
                time.sleep(6)
        else:
            with allure.step(f"Step{iStep}:Remove fault of VCANH connnects to VCANL"):
                modbus.write_single_coil(DO_Address_single.Y1.value,0x0000)
            time.sleep(1)
        iStep += 1
        del modbus
        return iStep

    def V_ConnectCanH_CanL(self, Eanble,iStep):
        
        modbus = Modbus(Set_up.modbusCOM)
        if Eanble:
            self.Reset_Setup_Pcanlist(True)
            with allure.step(f"Step{iStep}:VCANH connects to VCANL"):
                modbus.write_single_coil(DO_Address_single.Y2.value,0x0001)
                time.sleep(6)
        else:
            with allure.step(f"Step{iStep}:Remove fault of VCANH connnects to VCANL"):
                modbus.write_single_coil(DO_Address_single.Y2.value,0x0000)
            time.sleep(1)
        iStep += 1
        del modbus
        return iStep

    def S_ConnectCanH_GND(self, Eanble,iStep):
        modbus = Modbus(Set_up.modbusCOM)
        if Eanble:
            self.Reset_Setup_Pcanlist(True)
            with allure.step(f"Step{iStep}:SCANH connects to GND"):
                modbus.write_single_coil(DO_Address_single.Y4.value,0x0001)
                time.sleep(6)
        else:
            with allure.step(f"Step{iStep}:Remove fault of SCANH connnects to GND"):
                modbus.write_single_coil(DO_Address_single.Y4.value,0x0000)
            time.sleep(1)
        iStep += 1
        del modbus
        return iStep

    def S_ConnectCanL_Vcc(self, Eanble,iStep):
        modbus = Modbus(Set_up.modbusCOM)
        if Eanble:
            self.Reset_Setup_Pcanlist(True)
            with allure.step(f"Step{iStep}:SCANH connects to VCC"):
                modbus.write_single_coil(DO_Address_single.Y5.value,0x0001)
                time.sleep(6)
        else:
            with allure.step(f"Step{iStep}:Remove fault of SCANH connnects to VCC"):
                modbus.write_single_coil(DO_Address_single.Y5.value,0x0000)
            time.sleep(1)
        iStep += 1
        del modbus
        return iStep

    def S_ConnectCanH_CanL(self, Eanble,iStep):
        modbus = Modbus(Set_up.modbusCOM)
        if Eanble:
            self.Reset_Setup_Pcanlist(True)
            with allure.step(f"Step{iStep}:SCANH connects to SCANL"):
                modbus.write_single_coil(DO_Address_single.Y6.value,0x0001)
                time.sleep(6)
                logging.info('Unicom SFCAN CanH_CanL,Wait 6s')
        else:
            with allure.step(f"Step{iStep}:Remove fault of SCANH connnects to SCANL"):
                modbus.write_single_coil(DO_Address_single.Y6.value,0x0000)
                logging.info('Disconnect SFCAN CanH_CanL')
            time.sleep(1.5)
        iStep += 1
        del modbus
        return iStep

    def set_signal_Year(self,value):
        self.write_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Year_2B6_S',value) 
        self.read_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Year_2B6_S')  

    def set_signal_Month(self,value):
        self.write_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Month_2B6_S',value)
        self.read_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Month_2B6_S')

    def set_signal_Day(self,value):
        self.write_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Day_2B6_S',value)
        self.read_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Day_2B6_S')

    def set_signal_Hour(self,value):
        self.write_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Hour_2B6_S',value) 
        self.read_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Hour_2B6_S') 

    def set_signal_Minute(self,value):
        self.write_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Minute_2B6_S',value)
        self.read_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Minute_2B6_S')
    
    def set_signal_Second(self,value):
        self.write_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Second_2B6_S',value)
        self.read_db_signal(Set_up.NetName,Set_up.nodeName,'Media_0x2B6','Date_Information_Second_2B6_S')

    def set_signal_Total_Distance(self,value):
        self.write_db_signal(Set_up.NetName,Set_up.nodeName,'Left_BCM_0x3D9','Total_Distance_3D9s5_S',value)
        self.read_db_signal(Set_up.NetName,Set_up.nodeName,'Left_BCM_0x3D9','Total_Distance_3D9s5_S')

    '''故障注入函数'''
    def setVariantCodeDet(self, Driver, dtcName, PASS=0,iStep=1):
        with allure.step(f'Step{iStep}:故障注入与消除'):
            logging.info("打开外部注入配置信息")
            Driver['CAN2'].sendAndread_CMD_Shell(0x114,'profile 0',10)
            # 打开外部注入配置信息

            
            Driver['CAN2'].sendAndread_CMD_Shell(0x114,f'cmd set gExInj_{dtcName}_Enable 0 C 1 1',10)
            # 设置故障状态 0=PASS -1=FAIL
            if dtcName == 'MasterRdTemp':
                if PASS == 0:
                    PASS = 60.0
                else:
                    PASS = 117.6
                Driver['CAN2'].sendAndread_CMD_Shell(0x114,f'cmd set gExInj_{dtcName}_val 0 f 1 {PASS}',10)
                time.sleep(10)
            else:
                Driver['CAN2'].sendAndread_CMD_Shell(0x114,f'cmd set gExInj_{dtcName}_val 0 s 1 {PASS}',10)

            logging.info(f'{dtcName} 状态为: [{PASS}]') 
            time.sleep(0.5) 
            iStep += 1

        return iStep


    '''故障注入函数'''
    def test_wdg(self, Driver,iStep):
        with allure.step(f'Step{iStep}:故障注入与消除'):
            logging.info("打开外部注入配置信息")
            Driver['CAN2'].sendAndread_CMD_Shell(0x114,'profile 0',10)
            # 打开外部注入配置信息
            Driver['CAN2'].sendAndread_CMD_Shell(0x114,f'cmd fsmErrInjection test_wdg',10)
            time.sleep(0.5) 
            iStep += 1

        return iStep

    
    '''故障注入函数'''
    def GetRadarInfo(self, Driver, infoName,iStep=1):
        with allure.step(f'Step{iStep}:故障注入与消除'):
            Driver['CAN2'].sendAndread_CMD_Shell(0x114,'profile 0',10)
            # 打开外部注入配置信息
            RadarInfo = float(Driver['CAN2'].sendAndread_CMD_Shell(0x114,f'cmd get {infoName} 0 f 1',10))

            logging.info(f'{infoName} = [{RadarInfo}]') 
            time.sleep(0.5) 
            iStep += 1

        return iStep, RadarInfo

   
    '''断电重启ECU'''
    def restartMRR_Power(self,Driver, iStep=1):
        """
        断电重启产品.
        Parameters:
        Driver - Driver.    
        iStep - 第几步,默认为步骤1.       

        Returns:
            第几步
        """
        with allure.step(f'Step{iStep}:ECU下电再次上电'):
            self.Reset_Setup_Pcanlist(True)
            self.write_db_signal('Vehicle_CAN', 'BCM', 'Left_BCM_0x12D', 'BCMPower_Gear_12D_S', 1)
            time.sleep(0.5)
            Driver['power'].Enable(False)
            # self.fush_q_buff()
            logging.info('Power off the ECU')
            time.sleep(1)
            Driver['power'].Enable(True)
            logging.info('Wait 1s, Power on the ECU')
            self.write_db_signal('Vehicle_CAN', 'BCM', 'Left_BCM_0x12D', 'BCMPower_Gear_12D_S', 3)
            time.sleep(3)
            logging.info('Wait 3s, Restart the device OK')

            Set_up.MRR_0x66F_data.clear()
            Set_up.MRR_0x66F_time.clear()
            iStep += 1
        return iStep
    
    '''请求1101重启ECU'''
    def restartMRR_11(self,Driver, iStep=1):
        """
        使用1101重启产品.
        Parameters:
        Driver - Driver.    
        iStep - 第几步,默认为步骤1.       

        Returns:
            第几步
        """
        with allure.step(f'Step{iStep}:request 1101 restart ECU'):
            self.Reset_Setup_Pcanlist(True)
            self.write_db_signal('Vehicle_CAN', 'BCM', 'Left_BCM_0x12D', 'BCMPower_Gear_12D_S', 1)
            time.sleep(1)
            iStep, uds_resp, size = self.checkReqResp(Driver, "11 01", "51 01", 3, iStep, True)
            time.sleep(3)
            self.write_db_signal('Vehicle_CAN', 'BCM', 'Left_BCM_0x12D', 'BCMPower_Gear_12D_S', 3)
            time.sleep(3)
            logging.info('Wait 6s, Restart the device OK')
            iStep += 1
        return iStep

    '''读取Pcan数据'''
    def read_PCAN_Frame(self):
        respData = []
        respLen = 0
        uds_resp, uds_resp_size = self.read_frame()
        for i in range(uds_resp_size):
            if uds_resp['AIdentifier'][i] == Set_up.resID:
                if(uds_resp['ADatas'][0][0] & 0xF0)<< 8 == 1: 
                    respLen =  (uds_resp['ADatas'][0][0] & 0x0F) + uds_resp['ADatas'][0][1] +2
                else:
                    respLen =  uds_resp['ADatas'][0][0] + 1
                respData =  uds_resp['ADatas'][i][0:8]
                break
        for i in range(1,uds_resp_size):
            respData += uds_resp['ADatas'][i][1:8]
        if uds_resp_size > 0:
            respData = respData[0:(respLen)]
            actuRespStr = binascii.b2a_hex(bytearray(respData), ' ')    
            logging.error('P_CAN responseID:[0x{0:X}], Data:[{1}]'.format(Set_up.resID, actuRespStr)) 

        return respData, respLen

    '''判断除了三个初始故障是否有新的故障产生'''
    def delInitialFailure(self, iStep,data):
        with allure.step(f'Step{iStep}: Determine whether there is any other DTC'):
            for i in range(len(Set_up.InitialFailure)):
                if set(Set_up.InitialFailure[i]) < set(data):
                    for j in range(len(Set_up.InitialFailure[i])):
                        data.remove(Set_up.InitialFailure[i][j])
            with assume: assert data == [0x59,0x02,0x09]
            if data != [0x59,0x02,0x09]:
                actuRespStr = binascii.b2a_hex(bytearray(data[3:]), ' ') 
                logging.error('response:[{0}]'.format(actuRespStr)) 
            iStep += 1
        
        return iStep

    '''采用故障注入方式清除初始故障'''
    def clearInitialFilure(self,Driver,iStep):
        with allure.step(f'Step{iStep}: Clear DTC [ACD178 ACD278 ACE655]'):
            logging.info("采用故障注入，清除故障[ACD178 ACD278 ACE655]".center(30, '*'))
            Driver['CAN2'].sendAndread_CMD_Shell(0x114,'profile 0',20)

            Driver['CAN2'].sendAndread_CMD_Shell(0x114,'cmd set gExInj_AlignmentNeverDone_Enable 0 C 1 1',20)
            Driver['CAN2'].sendAndread_CMD_Shell(0x114,'cmd set gExInj_AlignmentNeverDone_val 0 s 1 0',20)

            Driver['CAN2'].sendAndread_CMD_Shell(0x114,'cmd set gExInj_AlignmentNotDone_Enable 0 C 1 1',20)
            Driver['CAN2'].sendAndread_CMD_Shell(0x114,'cmd set gExInj_AlignmentNotDone_val 0 s 1 0',20)

            Driver['CAN2'].sendAndread_CMD_Shell(0x114,'cmd set gExInj_VariantCodeDet_Enable 0 C 1 1',20)
            Driver['CAN2'].sendAndread_CMD_Shell(0x114,'cmd set gExInj_VariantCodeDet_val 0 s 1 0',20)
            time.sleep(1)
            iStep += 1
        return iStep

    def Reset_Setup_Pcanlist(self, Status=True):
        Set_up.startCheck = False
        for i in Set_up.PCAN_list:
            Set_up.PCAN_list[i][1] = True
        for i in Set_up.PCAN_list_BOCH: 
            Set_up.PCAN_list_BOCH[i][1] = True 

    def wakeup_ctrl(self,enable):
        if enable:
            self.wake_ref = self.send_CANFrame_Cycle(0x188,[0x88,0x88,0x00,0x00,0x00,0x00,0x00,0x88],1)#, Set_up.CAN_Type)
        else:
            self.stop_FrANFrame_Cycle(self.wake_ref)
        pass
    
    def send_sync_frame(self):
        timeNumber = time.time()
        syncTime = int(timeNumber)
        logging.info('send s = [{0}]'.format(syncTime))
        send_SYNC_Frame = [0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09]
        packed_bytes = struct.pack('<l', syncTime)
        send_SYNC_Frame[4] = packed_bytes[3]
        send_SYNC_Frame[5] = packed_bytes[2]
        send_SYNC_Frame[6] = packed_bytes[1]
        send_SYNC_Frame[7] = packed_bytes[0]
        send_SYNC_Frame[2] = 0 | (send_SYNC_Frame[2] & 0xF0)
        crcData = list(send_SYNC_Frame[0:9])
        crcData.pop(1)
        crc16 = Crc8_8H2F(crcData,8)
        send_SYNC_Frame[1] = crc16
        send_SYNC_Frame.pop()
        self.send_Frame(0x2F6,send_SYNC_Frame)

        return timeNumber


    def send_fup_frame(self, timeNumber):
        fupTime = int((timeNumber % 1) * 1000000000)
        logging.info('send ns = [{0}]'.format(fupTime))
        send_FUP_Frame = [0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09]
        packed_bytes = struct.pack('<l', fupTime)
        send_FUP_Frame[4] = packed_bytes[3]
        send_FUP_Frame[5] = packed_bytes[2]
        send_FUP_Frame[6] = packed_bytes[1]
        send_FUP_Frame[7] = packed_bytes[0]
        send_FUP_Frame[2] = 0 | (send_FUP_Frame[2] & 0xF0)
        crcData = list(send_FUP_Frame[0:9])
        crcData.pop(1)
        crc16 = Crc8_8H2F(crcData,8)
        send_FUP_Frame[1] = crc16

        send_FUP_Frame.pop()
        self.send_Frame(0x2F6,send_FUP_Frame)


    '''读取Pcan数据'''
    def read_PCAN_Time_Frame(self, enable = False):
        respData = []
        self.fush_q_buff()
        i = 0
        time.sleep(0.1)
        uds_resp, uds_resp_size = self.read_frame()
        for i in range(uds_resp_size):
            if uds_resp['AIdentifier'][i] == 0x66F:
                respData =  uds_resp['ADatas'][i][0:16]
                readTime = uds_resp['ATimeUs'][i]
                if enable == False:
                    i = 20
                    break
                else:
                    if respData[4] == 0x0C:
                        i = 20
                        break

        for i in range(0,uds_resp_size):
            respData += uds_resp['ADatas'][i][0:16]
        if uds_resp_size > 0:
            respData = respData[0:16]
            actuRespStr = binascii.b2a_hex(bytearray(respData), ' ')    
            logging.error('P_CAN responseID:[0x{0:X}], Data:[{1}]'.format(0x66F, actuRespStr)) 

        return respData, time.time() * 1000





# run main
if __name__ == "__main__":
    import os
    root = os.getcwd()
    project_DBC_File_CAN = os.path.join(root, r'data\MRR_20220901.dbc')
    logging.info(project_DBC_File_CAN)
    try:


        rbs = real_CAN(drive_type = 'USE_TS_TC1011_DEVICE',    # USE_TS_TC1014_DEVICE /   USE_TS_VIRTUAL_DEVICE
                    configure_baudrate = {'CAN_Type':'CANFD','ArbRate':500,'DataRate':2000,'TermResistor':True}
                    )
        rbs.load_dbc(project_DBC_File_CAN)
        # rbs.register_event_can_T_R(OnCANevent)
        # rbs.register_event_canfd_T_R(OnCANFDevent)
        rbs.set_0x222_rolling_counter_error(enable=False)
        rbs.register_event_canfd_T_pre(OnCANPreFDevent)
        
        rbs.connect_application()
        rbs.RBS_Config('Vehicle_CAN',['BCM'])

        logging.info('send frame')
        rbs.send_Frame(0x666,[0x61,2,3,4,5,6,7,8,
                              0x22,2,3,4,5,6,7,8,
                              0x23,2,3,4,5,6,7,8,
                              0x24,2,3,4,5,6,7,8,
                              0x25,2,3,4,5,6,7,8,
                              0x26,2,3,4,5,6,7,8,
                              0x27,2,3,4,5,6,7,8,
                              0x28,2,3,4,5,6,7,8],'CANFD')
        rbs.send_Frame(0x777,[0x71,2,3,4,5,6,7,8,],'CAN')
        rbs.send_Frame(0x777,[0x81,2,3,4,5,6,7,8,],'CAN')
        rbs.send_Frame(0x444,[0x41,2,3,4,5,6,7,8,],'CAN')

        a =rbs.send_CANFrame_Cycle(0x22,[0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88],100)
        
        logging.info('step1_wait_1000_:::::')
        rbs.fush_q_buff()
        rbs.TS_delay(1000)
        rbs.read_frame()

        logging.info('step2__wait_2000_:::::') 
        rbs.fush_q_buff()
        rbs.TS_delay(2000)
        rbs.read_frame()

        logging.info('step2__wait_2000_:::::') 
        rbs.fush_q_buff()
        rbs.TS_delay(2000)
        rbs.read_frame()

        logging.info('step3__wait_3000_:::::') 
        rbs.fush_q_buff()
        rbs.TS_delay(3000)
        rbs.read_frame()

        ttttt = rbs.sendAndread_CMD_Shell(0x114,'test 12',500)
        ttttt = rbs.sendAndread_CMD_Shell(0x114,'test 12',500)
        logging.info(ttttt)
        rbs.stop_FrANFrame_Cycle(a)

        rbs.write_db_signal('SCAN4','GW','ABS1','ABS1_FLWheelSpd',34.0)

        aa = rbs.read_db_signal('SCAN4','GW','ABS1','ABS1_FLWheelSpd')
        logging.info('read rbs signal value is ',aa)

        diag = TSCAN_UDS()
        diag.req_and_res_can([0x22,0xf1,0x90],3)
        diag.UDS_can_delete()

        # obj = HIL_Obj(rbs)
        # obj.setDaemon(True)
        # obj.open()
        # obj.obj_sent()
        # obj.start()
        # obj.last_warninh_data
        # obj.warning_data

        rbs.dis_connect_application()

        logging.info('Over All')
        import sys
        sys.exit(0)

    except Exception as e :
        rbs.dis_connect_application()
        import sys
        import traceback
        logging.info(traceback.print_exc())
        sys.exit(0)
        pass
    
    except KeyboardInterrupt :
        rbs.dis_connect_application()
        import sys
        import traceback
        logging.info(traceback.print_exc())
        sys.exit(0)
        pass
